package com.intretech.umsin.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.intretech.umsin.datasource.dao.KernDAO;
import com.intretech.umsin.security.satoken.utils.LoginHelper;
import com.intretech.umsin.system.converter.SysMenuVoEntityConverter;
import com.intretech.umsin.system.entity.SysMenuEntity;
import com.intretech.umsin.system.mapper.SysMenuMapper;
import com.intretech.umsin.system.param.SysMenuParam;
import com.intretech.umsin.system.service.SysMenuService;
import com.intretech.umsin.system.vo.SysMenuVo;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.*;


/**
* @version V1.0
* 菜单权限:sys_menu 对应商业服务实现.
* @ClassName: SysMenuServiceImpl
* @Description: 菜单权限:sys_menu 对应商业服务实现.
* @author: 李启联
* @date:   2022-8-6 14:37:22
* @Copyright: Copyright (c) 2022
*/
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenuEntity> implements SysMenuService {

    @Autowired
    private SysMenuVoEntityConverter sysMenuVoEntityConverter;

    @Autowired
    KernDAO kernDAO;


    /**
    * 根据ID查询单个菜单权限对象
    * @param id 组键ID
    * @return 单个菜单权限VO对象
    */
    public SysMenuVo queryById(Serializable id){
        if (id == null) {return null;}
        return sysMenuVoEntityConverter.reverseFromTarget(this.getById(id));
    }


    /**
    * 根据ID集合查询返回菜单权限列表
    * @param idList 组键ID集合
    * @return 菜单权限列表
    */
    public List<SysMenuVo> queryByIds(Collection<? extends Serializable> idList){
        if(CollectionUtils.isEmpty(idList)){return null;}
        return sysMenuVoEntityConverter.reverseFromTarget(this.listByIds(idList));
    }


    /**
    * 分页查询 菜单权限 信息
    * @param page 分页对象
    * @param param 查询参数
    * @return IPage<SysMenuVo> 分页对象
    */
    @Override
    public IPage<SysMenuVo> queryForPage(IPage page,SysMenuParam param){
      IPage<SysMenuEntity> page0 = this.page(page,createQueryWrapper(param));
      IPage<SysMenuVo> pageResult = page0.convert(e -> sysMenuVoEntityConverter.reverseFromTarget(e));
      return pageResult;
    }


    /**
    * 根据条件查询返回 菜单权限 对象列表
    * @param  param 查询参数
    * @return 菜单权限 对象列表
    */
    @Override
    public List<SysMenuVo> queryForList(SysMenuParam param) {
        List<SysMenuEntity> list = this.list(createQueryWrapper(param));
        return sysMenuVoEntityConverter.reverseFromTarget(list);
    }

    /**
    * 构建查询条件
    * @param param 查询参数实体对象
    * @return 构建后的QueryWrapper查询条件
    */
    private QueryWrapper<SysMenuEntity> createQueryWrapper(SysMenuParam param){
        QueryWrapper<SysMenuEntity> queryWrapper = new QueryWrapper<>();
        if(ObjectUtils.isEmpty(param)) { return queryWrapper; }
        Optional<SysMenuParam> op = Optional.of(param);
        queryWrapper.lambda()
                .eq(op.map(SysMenuParam::getId).isPresent(),SysMenuEntity::getId,param.getId())
                .eq(op.map(SysMenuParam::getMenuName).filter(StringUtils::isNotBlank).isPresent(),SysMenuEntity::getMenuName,param.getMenuName())
                .eq(op.map(SysMenuParam::getParentId).isPresent(),SysMenuEntity::getParentId,param.getParentId())
                .eq(op.map(SysMenuParam::getOrderNum).isPresent(),SysMenuEntity::getOrderNum,param.getOrderNum())
                .eq(op.map(SysMenuParam::getPath).filter(StringUtils::isNotBlank).isPresent(),SysMenuEntity::getPath,param.getPath())
                .eq(op.map(SysMenuParam::getComponent).filter(StringUtils::isNotBlank).isPresent(),SysMenuEntity::getComponent,param.getComponent())
                .eq(op.map(SysMenuParam::getQueryParam).filter(StringUtils::isNotBlank).isPresent(),SysMenuEntity::getQueryParam,param.getQueryParam())
                .eq(op.map(SysMenuParam::getIsFrame).isPresent(),SysMenuEntity::getIsFrame,param.getIsFrame())
                .eq(op.map(SysMenuParam::getIsCache).isPresent(),SysMenuEntity::getIsCache,param.getIsCache())
                .eq(op.map(SysMenuParam::getMenuType).filter(StringUtils::isNotBlank).isPresent(),SysMenuEntity::getMenuType,param.getMenuType())
                .eq(op.map(SysMenuParam::getVisible).filter(StringUtils::isNotBlank).isPresent(),SysMenuEntity::getVisible,param.getVisible())
                .eq(op.map(SysMenuParam::getStatus).filter(StringUtils::isNotBlank).isPresent(),SysMenuEntity::getStatus,param.getStatus())
                .eq(op.map(SysMenuParam::getPerms).filter(StringUtils::isNotBlank).isPresent(),SysMenuEntity::getPerms,param.getPerms())
                .eq(op.map(SysMenuParam::getIcon).filter(StringUtils::isNotBlank).isPresent(),SysMenuEntity::getIcon,param.getIcon())
                .eq(op.map(SysMenuParam::getRemark).filter(StringUtils::isNotBlank).isPresent(),SysMenuEntity::getRemark,param.getRemark())
                .eq(op.map(SysMenuParam::getUpdater).filter(StringUtils::isNotBlank).isPresent(),SysMenuEntity::getUpdater,param.getUpdater())
                .eq(op.map(SysMenuParam::getCreateDate).isPresent(),SysMenuEntity::getCreateDate,param.getCreateDate())
                .eq(op.map(SysMenuParam::getUpdateDate).isPresent(),SysMenuEntity::getUpdateDate,param.getUpdateDate())
        ;
        return queryWrapper;
    }

    /**
    * 添加菜单权限到数据库
    * @param vo  菜单权限 VO对象
    * @return 添加后的菜单权限 VO对象
    */
    @Override
    public SysMenuVo add(SysMenuVo vo) {
        if (ObjectUtils.isEmpty(vo)) {return null;}
        SysMenuEntity entity = sysMenuVoEntityConverter.convertToTarget(vo);
        if(this.save(entity)){
            return sysMenuVoEntityConverter.reverseFromTarget(this.getById(entity.getId()));
        }else {
            throw new RuntimeException("添加 菜单权限 单个对象失败!");
            //return null;
        }
    }

    /**
    * 添加菜单权限集合列表到数据库
    * @param vos  菜单权限 VO对象列表
    * @return 添加后的菜单权限 VO对象集合列表
    */
    @Override
    public List<SysMenuVo> adds(List<SysMenuVo> vos) {
        if (CollectionUtils.isEmpty(vos)) { return null; }
        List<SysMenuEntity> entities = sysMenuVoEntityConverter.convertToTarget(vos);
        if(this.saveBatch(entities)){
            List<Serializable> ids = new ArrayList<>();
            entities.forEach(e->{ids.add(e.getId());});
            return sysMenuVoEntityConverter.reverseFromTarget(this.listByIds(ids));
        }else {
           throw new RuntimeException("添加 菜单权限 集合列表失败!");
           //return null;
        }
    }

    /**
    * 更新菜单权限到数据库
    * @param vo 要更新的菜单权限 VO对象
    * @return 更新后的菜单权限 VO对象
    */
    @Override
    public SysMenuVo modify(SysMenuVo vo) {
        if (ObjectUtils.isEmpty(vo)) {return null;}
        SysMenuEntity entity = sysMenuVoEntityConverter.convertToTarget(vo);
        if(this.updateById(entity)){
            return sysMenuVoEntityConverter.reverseFromTarget(this.getById(entity.getId()));
        }else {
            throw new RuntimeException("更新菜单权限单个对象失败!");
            //return null;
        }
    }

    /**
    * 更新菜单权限集合列表到数据库
    * @param vos 要更新的菜单权限 VO对象集合
    * @return 更新后的菜单权限 VO对象集合
    */
    @Override
    public List<SysMenuVo> modifys(List<SysMenuVo> vos) {
        if (CollectionUtils.isEmpty(vos)) { return null; }
        List<SysMenuEntity> entities = sysMenuVoEntityConverter.convertToTarget(vos);
        if(this.updateBatchById(entities)){
            List<Serializable> ids = new ArrayList<>();
            entities.forEach(e->{ids.add(e.getId());});
            return sysMenuVoEntityConverter.reverseFromTarget(this.listByIds(ids));
        }else {
            throw new RuntimeException("更新菜单权限集合列表失败!");
            //return null;
        }
    }

    /**
     * 根据用户查询系统菜单列表
     *
     * @param userId 用户ID
     * @return 菜单列表
     */
    @Override
    public List<SysMenuVo> selectMenuList(Long userId) {
        String sql = "select distinct m.* from sys_menu m\n" +
                " left join sys_role_menu rm on m.id = rm.menu_id\n" +
                " left join sys_user_role sur on rm.role_id = sur.role_id\n" +
                " left join sys_role r on r.id = sur.role_id\n" +
                " where m.status = '0' and r.status = '0' and sur.user_id = ?";
        List<SysMenuVo> sysMenus = null;
        try {
            sysMenus = kernDAO.queryForList(sql, SysMenuVo.class, userId);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return sysMenus;
    }

    /**
     * 根据用户ID查询权限
     *
     * @param userId 用户ID
     * @return 权限列表
     */
    @Override
    public Set<String> selectMenuPermsByUserId(Long userId) {
        Set<String> perms = new HashSet<String>();
        // 管理员拥有所有权限
        if (LoginHelper.isAdmin(userId)) {
            perms.add("*:*:*");
        } else {
            List<SysMenuVo> sysMenus = selectMenuList(userId);
            for (SysMenuVo menu : sysMenus) {
                if (StringUtils.isNotEmpty(menu.getPerms())) {
                    perms.addAll(Arrays.asList(menu.getPerms().trim().split(",")));
                }
            }
        }
        return perms;
    }

}

